using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid.ViewInfo;
using DevExpress.Data.Filtering;
using ChuanPlus.DAO;
namespace ChuanPlus.FormControl
{
    public partial class ControlManageRedInvoice : DevExpress.XtraEditors.XtraUserControl
    {
        DataTable m_dtEmptyRedInv = null;
        DataTable m_dtAlterableProduct = null;
        List<AlternateProduct> m_lstAlterProduct = new List<AlternateProduct>();
        DataRow m_drCurrentOrder = null;
        public ControlManageRedInvoice()
        {
            InitializeComponent();
            ////CriteriaOperator opeLeft = new BinaryOperator(new OperandProperty("OrderDetails[0].VAT"), new OperandValue(0), BinaryOperatorType.Greater);
            //CriteriaOperator opeRight = new BinaryOperator(new OperandProperty("RedInvNo"), new OperandValue(""), BinaryOperatorType.Equal);
            //CriteriaOperator filter = new GroupOperator(GroupOperatorType.And, new CriteriaOperator[2] { opeLeft, opeRight });
            //xpColOrders.AddRange(OrderDAO.GetEmptyRebInvoiceOrder());

            try
            {
                m_dtEmptyRedInv = OrderDAO.GetEmptyRebInvoiceOrder();
                m_dtAlterableProduct = ProductDAO.GetAlterableProduct();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
                throw;
            }
            
            gridTop.DataSource = m_dtEmptyRedInv;
            gridLeft.DataSource = m_dtAlterableProduct;
            gridRight.DataSource = m_lstAlterProduct;
        }

        private void gridView1_Click(object sender, EventArgs e)
        {
            // Checks whether an end-used has double clicked the row indicator.
            GridHitInfo hi = gridView1.CalcHitInfo(gridTop.PointToClient(MousePosition));
            if (!hi.InRow) return;
            // Retrieves the persistent object that corresponds to the currently focused grid row.
            int DSRowIndex = gridView1.Columns.View.GetDataSourceRowIndex(gridView1.FocusedRowHandle);
            m_drCurrentOrder = m_dtEmptyRedInv.Rows[DSRowIndex];
            string orderID = m_drCurrentOrder["OrderID"].ToString();
            lblOrderID.Text = orderID;
            textAmount.Text = m_drCurrentOrder["Total"].ToString();
        }
       

        private void gridView2_DoubleClick(object sender, EventArgs e)
        {
            // Checks whether an end-used has double clicked the row indicator.
            GridHitInfo hi = gridView2.CalcHitInfo(gridLeft.PointToClient(MousePosition));
            if (!hi.InRow) return;
            // Retrieves the persistent object that corresponds to the currently focused grid row.
            int DSRowIndex = gridView2.Columns.View.GetDataSourceRowIndex(gridView2.FocusedRowHandle);
            DataRow row = m_dtAlterableProduct.Rows[DSRowIndex];
            int id = Convert.ToInt32(row["ID"]);
            Product p = ProductDAO.GetProduct(id);
            AlternateProduct alterProduct = new AlternateProduct(p,p.ItemCode, p.UnitPrice, 1,Convert.ToDouble(row["Qty"]));
            alterProduct.RefreshTotal();    // recalculate tax
            if (m_lstAlterProduct.Contains(alterProduct)) return;   // do not add duplicate AlternateProduct
            m_lstAlterProduct.Add(alterProduct);
            gridRight.RefreshDataSource();
        }

        private void gridView3_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                // Retrieves the persistent object that corresponds to the currently focused grid row.
                int DSRowIndex = gridView3.Columns.View.GetDataSourceRowIndex(gridView3.FocusedRowHandle);
                m_lstAlterProduct.RemoveAt(DSRowIndex);     // do not add to list if product is added      
                gridRight.RefreshDataSource();
            }
        }

        private void gridView3_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            int DSRowIndex = gridView2.Columns.View.GetDataSourceRowIndex(e.RowHandle);
            AlternateProduct alterProduct = m_lstAlterProduct[DSRowIndex];
            if (e.Column.FieldName == "RedInvQuantity")
                alterProduct.RedInvQuantity= Double.Parse(e.Value.ToString());
            else if (e.Column.FieldName == "UnitPrice")
                alterProduct.UnitPrice = Double.Parse(e.Value.ToString());
            alterProduct.RefreshTotal();
            gridRight.RefreshDataSource();
        }

        private void ButtonSubmit_Click(object sender, EventArgs e)
        {

            if (!FormValidation()) return;
            DialogResult result =  MessageBox.Show("Are you sure want to create a new Purchase Order?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1);
            if (result.ToString() == "Yes")
            {
                if (m_lstAlterProduct.Count > 0)
                {
                    foreach (AlternateProduct item in m_lstAlterProduct)
                    {
                        item.product.RedInvQty -= item.RedInvQuantity;
                        item.product.Save();
                    }
                }
                Order order = OrderDAO.GetOrderByID(m_drCurrentOrder["OrderID"].ToString());
                order.RedInvNo = textRedInvNo.Text;
                order.Save();
                Reset();
                MessageBox.Show("Red invoice number "+ textRedInvNo.Text +" is assigned to PO sucessfully","Message");
            }
        }

        private void Reset()
        {
            try
            {
                m_dtEmptyRedInv = OrderDAO.GetEmptyRebInvoiceOrder();
                m_dtAlterableProduct = ProductDAO.GetAlterableProduct();
                m_lstAlterProduct.Clear();
                gridTop.RefreshDataSource();
                gridLeft.RefreshDataSource();
                gridRight.RefreshDataSource();
            }
            catch (Exception)
            {
            
                throw;
            } 
        }
        public bool FormValidation()
        {
            
            if (m_drCurrentOrder == null)
            {
                MessageBox.Show("Please select a PO to create red invoice","Message");
                return false;
            }
            if (textRedInvNo.Text.Trim() == "")
            {
                MessageBox.Show("Enter Red Invoice no for this PO", "Message");
                textRedInvNo.Focus();
                return false;
            }
            if (m_drCurrentOrder != null)
            {
            	if(m_drCurrentOrder["DistributorName"].ToString() == "CBD")
                    if(m_lstAlterProduct.Count <= 0)
                    {
                        MessageBox.Show("Please select alternate product for this PO","Message");
                        return false;
                    }
            }
            double total = Convert.ToDouble(gridView3.Columns["Total"].SummaryItem.SummaryValue);
            if (Math.Abs(total - double.Parse(textAmount.Text)) > double.Parse(textAmount.Text) * 0.1)
            {
                MessageBox.Show("Total Amount and required amount does not match", "Message");
                return false;
            }
            return true;
        }

        private void gridView3_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.BaseContainerValidateEditorEventArgs e)
        {
            if (gridView3.FocusedColumn.FieldName == "RedInvQuantity")
            {

                int DSRowIndex = gridView3.Columns.View.GetDataSourceRowIndex(gridView3.FocusedRowHandle);
                AlternateProduct alterProduct = m_lstAlterProduct[DSRowIndex];

                double availableRedInv = alterProduct.product.RedInvQty - alterProduct.QtyBalance;
                //Get the currently edited value
                double qty = Convert.ToDouble(e.Value);
                //Specify validation criteria
                if (qty < 0)
                {
                    e.Valid = false;
                    e.ErrorText = "Enter a positive value";
                }
                if (qty > availableRedInv)
                {
                    e.Valid = false;
                    e.ErrorText = "Reduce the quantity (" + availableRedInv + " is maximum)";
                }
            }
            if (gridView3.FocusedColumn.FieldName == "UnitPrice")
            {
                if (Convert.ToDouble(e.Value) < 0)
                {
                    e.Valid = false;
                    e.ErrorText = "Enter a positive value";
                }
            }
        }

        private void ButtonReset_Click(object sender, EventArgs e)
        {
            Reset();
        }

    }
    public class AlternateProduct
    {
        private Product _Product;
        public Product product
        {
            get { return _Product; }
            set { _Product = value; }
        }
        private string _ItemCode;
        public string ItemCode
        {
            get { return _ItemCode; }
            set { _ItemCode = value; }
        }
        private double _UnitPrice;
        public double UnitPrice
        {
            get { return _UnitPrice; }
            set { _UnitPrice = value; }
        }
        private double _RedInvQuantity;
        public double RedInvQuantity
        {
            get { return _RedInvQuantity; }
            set { _RedInvQuantity = value; }
        }
        private double _QtyBalance;
        public double QtyBalance
        {
            get { return _QtyBalance; }
            set { _QtyBalance = value; }
        }
        private double _Total;
        public double Total
        {
            get { return _Total; }
            set { _Total = value; }
        }
        private double _Tax;
        public double Tax
        {
            get { return _Tax; }
            set { _Tax = value; }
        }
        public override bool Equals(object obj)
        {
            bool result = true;
            if (obj == null) result = false;
            try
            {
                AlternateProduct p = (AlternateProduct)obj;
                if (p.product.ID == this.product.ID)
                    result = true;
                else
                    result = false;
            }
            catch
            {
                result = false;
            }
            return result;
        }
        public override int GetHashCode()
        {
            return base.GetHashCode();
        }
        /// <summary>
        /// Initializes a new instance of the AlternateProduct class.
        /// </summary>
        /// <param name="product"></param>
        /// <param name="itemCode"></param>
        /// <param name="unitPrice"></param>
        /// <param name="redInvQuantity"></param>
        /// <param name="total"></param>
        public AlternateProduct(Product product, string itemCode, double unitPrice, double redInvQuantity, double QtyBalance)
        {
            _Product = product;
            _ItemCode = itemCode;
            _UnitPrice = unitPrice;
            _RedInvQuantity = redInvQuantity;
            _QtyBalance = QtyBalance;
        }
        public void RefreshTotal()
        {            
                Tax = (RedInvQuantity * UnitPrice * product.Tax) / 100;
                _Total = (RedInvQuantity * UnitPrice) + Tax;            
        }
    }
}
